package cn.edu.neu.lab603.cloudeval.monitor

import cn.edu.neu.lab603.cloudeval.CloudEval
import cn.edu.neu.lab603.cloudeval.entity.CloudTask
import cn.edu.neu.lab603.cloudeval.entity.CloudTask.{FinishEvent, SubmissionEvent}
import cn.edu.neu.lab603.des.{SimMetric, SimMonitor}
import com.typesafe.scalalogging.LazyLogging

import scala.collection.mutable

/** 云计算计划任务执行延迟时间的监控。
  * 通过比较执行时间和实际执行时间作差。
  *
  * Created by yfwz100 on 16/9/24.
  */
class CloudletExecDelayMetric extends SimMonitor[CloudEval] with SimMetric[Double] with LazyLogging {

  private val startMap = new mutable.HashMap[Long, Int]
  val stats = new mutable.HashMap[Long, Int]

  override def isMatch(context: CloudEval): Boolean = {
    val task = context.getCurrentTask
    task.isInstanceOf[SubmissionEvent] || task.isInstanceOf[FinishEvent]
  }

  override def before(context: CloudEval): Unit = {}

  override def after(context: CloudEval): Unit = {
    implicit val simulation = context
    val task = context.getCurrentTask
    val clock = context.getCurrentClock
    task match {
      case _: SubmissionEvent => // 记录首次提交以及首次执行的情况
        for (cloudlet <- SubmissionEvent.getCurrentCloudlets) {
          if (cloudlet.getStatus == CloudTask.Status.READY) {
            startMap(cloudlet.cloudletNo) = clock
          }
        }

      case t: FinishEvent =>
        val cloudlet = t.cloudlet
        if (cloudlet.getStatus == CloudTask.Status.STOPPED) {
          stats(cloudlet.cloudletNo) = (clock - startMap(cloudlet.cloudletNo)) - cloudlet.length
        }
    }
  }

  def getDelaySum: Int = stats.values.sum

  override def getCurrentValue: Double = getDelaySum
}
